---
title: Configuring Cache Backends
description: How to configure Apollo Server's cache
---

Many Apollo Server features take advantage of a cache backend (these features include [automatic persisted queries](./apq), the [response cache plugin](./caching#caching-with-responsecacheplugin-advanced), and [`RESTDataSource`](../data/fetching-rest)). Apollo Server uses an in-memory cache by default, but you can configure it to use a different backend, such as Redis or Memcached.

You can specify a cache backend by passing a `cache` option to the `ApolloServer` constructor. Your specified cache backend must implement the [`KeyValueCache`](https://github.com/apollographql/apollo-utils/tree/main/packages/keyValueCache#keyvaluecache-interface) interface from the `@apollo/utils.keyvaluecache` package.

There are many cache backend implementations to choose from, including several implementations provided by Apollo. For example, Apollo maintains an implementation of `InMemoryLRUCache` in the `@apollo/utils.keyvaluecache` package. Apollo also provides a wrapper class for the  [`keyv` package](https://www.npmjs.com/package/keyv) (which implements several cache backends) named [`KeyvAdapter`](https://github.com/apollographql/apollo-utils/tree/main/packages/keyvAdapter#keyvadapter-class) in the `@apollo/utils.keyvadapter` package.

## Configuring in-memory caching

You can configure your server to use a different backend (such as Redis or Memcached) using the `cache` constructor option.

If you want to configure the default in-memory cache, Apollo provides the [`InMemoryLRUCache`](https://github.com/apollographql/apollo-utils/tree/main/packages/keyValueCache#inmemorylrucache) class from the `@apollo/utils.keyvaluecache` package.

The `InMemoryLRUCache` class is a wrapper around the `lru-cache` package and has a default maximum of approximately 30MiB of memory. You can configure an instance of `InMemoryLRUCache` with the same options as found in the `lru-cache` package, see the [`lru-cache` documentation](https://www.npmjs.com/package/lru-cache) for more details. You can use Apollo's `InMemoryLRUCache` by passing it to the `cache` option of the `ApolloServer` constructor like so:

```ts
import { InMemoryLRUCache } from '@apollo/utils.keyvaluecache';

const server = new ApolloServer({
  cache: new InMemoryLRUCache(),
});
```

> Apollo Server provides the equivalent of the above code snippet out-of-the-box and doesn't require you to install the `@apollo/utils.keyvaluecache` package.

In this example, we've increased the default size and provided a default TTL. For more information on these configuration options, see the [`lru-cache` documentation](https://www.npmjs.com/package/lru-cache).

```ts
import { InMemoryLRUCache } from '@apollo/utils.keyvaluecache';

const server = new ApolloServer({
  // ...
  cache: new InMemoryLRUCache({
    // ~100MiB
    maxSize: Math.pow(2, 20) * 100,
    // 5 minutes (in seconds)
    ttl: 300,
  }),
});
```

## Configuring external caching

Apollo no longer maintains any caching backends directly. Instead, we recommend using the [`keyv`](https://www.npmjs.com/package/keyv) package along with the [`KeyvAdapter`](https://github.com/apollographql/apollo-utils/tree/main/packages/keyvAdapter#keyvadapter-class) class provided by the `@apollo/utils.keyvadapter` package.

`KeyvAdapter` wraps a `Keyv` instance and implements the `KeyValueCache` interface which is required by Apollo Server. You can use the `KeyvAdapter` class to wrap a `Keyv` instance and provide it to the `cache` option of the `ApolloServer` constructor like so:

1. Install the required packages
```bash
npm install keyv @apollo/utils.keyvadapter
```

2. Configure the Apollo Server `cache`
```ts
import Keyv from 'keyv';
import { KeyvAdapter } from '@apollo/utils.keyvadapter';

const server = new ApolloServer({
  // ...,
  cache: new KeyvAdapter(new Keyv()), // highlight-line
});
```

## Implementing your own cache backend

If your requirements are specialized or you'd prefer to implement your own cache backend, you can implement the `KeyValueCache` interface and pass it to the `ApolloServer` constructor directly.

The `KeyValueCache` interface is shown below:
```ts
interface KeyValueCache<V> {
  get(key: string): Promise<V | undefined>;
  // ttl is specified in seconds
  set(key: string, value: V, options?: { ttl?: number | null }): Promise<void>;
  delete(key: string): Promise<boolean | void>;
}
```

## Configuring Redis

The `@keyv/redis` package uses the `ioredis` package under the hood. The second
options argument is passed through to the `ioredis.Redis` constructor. See the
[`ioredis` docs](https://github.com/luin/ioredis#connect-to-redis) for a list of
available options.

Start by installing the required packages:
```
npm install keyv @keyv/redis @apollo/utils.keyvadapter
```

### Single instance
```ts
import Keyv from "keyv";
import KeyvRedis from "@keyv/redis";
import { KeyvAdapter } from "@apollo/utils.keyvadapter";

const server = new ApolloServer({
  typeDefs,
  resolvers,
  cache: new KeyvAdapter(new Keyv(new KeyvRedis("redis://user:pass@localhost:6379"))), // highlight-line
});
```

### Redis Sentinel
```ts
import Keyv from "keyv";
import { KeyvAdapter } from "@apollo/utils.keyvadapter";

const server = new ApolloServer({
  typeDefs,
  resolvers,
  // highlight-start
  cache: new KeyvAdapter(new Keyv(
    new KeyvRedis("redis://user:pass@localhost:6379", {
      sentinels: [
        { host: "localhost", port: 26379 },
        { host: "localhost", port: 26380 },
      ],
    })
  )),
  // highlight-end
});
```

### Redis Cluster

The `@keyv/redis` package doesn't support `ioredis.Cluster` out of the box.
Instead, we can create our own `ioredis.Cluster` instance and pass that to
`keyv` as the `store` object. See the [`ioredis.Cluster`
docs](https://github.com/luin/ioredis#cluster) for a list of available options.

Start by installing the packages we'll need:
```
npm install keyv @keyv/redis ioredis @apollo/utils.keyvadapter
```

```ts
import Keyv from "keyv";
import KeyvRedis from "@keyv/redis";
import Redis from "ioredis";
import { KeyvAdapter } from "@apollo/utils.keyvadapter";

// highlight-start
const cluster = new Redis.Cluster([
  { host: "localhost", port: 26379 },
  { host: "localhost", port: 26380 },
]);
// highlight-end

const server = new ApolloServer({
  typeDefs,
  resolvers,
  // highlight-start
  cache: new KeyvAdapter(new Keyv({ store: new KeyvRedis(cluster) }), {
    disableBatchReads: true,
  }),
  // highlight-end
});
```

> Note the `disableBatchReads` option. This disables batching which isn't
supported by `ioredis.Cluster`.

## Configuring Memcache

The `@keyv/memcache` package uses the `memjs` package under the hood. Its second
options argument is passed to `memjs.Client.create()`. See the [`memjs`
docs](https://memjs.netlify.app/#section-3) for a list of available options.

Start by installing the required packages:
```
npm install keyv @keyv/memcache @apollo/utils.keyvadapter
```

```ts
import Keyv from "keyv";
import KeyvMemcache from "@keyv/memcache";
import { KeyvAdapter } from "@apollo/utils.keyvadapter";

// servers is a comma-separated list of strings
// highlight-start
const servers = [
  "user:pass@localhost:11211",
  "user:pass@localhost:11222"
].join(",");

const memcache = new KeyvMemcache(servers, {
  retries: 10,
  expires: 60,
});
// highlight-end

const server = new ApolloServer({
  typeDefs,
  resolvers,
  cache: new KeyvAdapter(new Keyv({ store: memcache })), // highlight-line
});
```

## Handling cache fetching errors

To provide error tolerance for cache backends that connect via a client (e.g., Redis), we recommend using the `ErrorsAreMissesCache` wrapper from [@apollo/utils.keyvaluecache](https://github.com/apollographql/apollo-utils/tree/main/packages/keyValueCache#errorsaremissescache). If the cache is unavailable and your request throws an error, `ErrorsAreMissesCache` treats that error as a cache miss. At the same time, your cache client can keep trying to reconnect to your cache backend until things are working again, like so:


```typescript
import Keyv from "keyv";
import KeyvRedis from "@keyv/redis";
import { KeyvAdapter } from "@apollo/utils.keyvadapter";
import { ErrorsAreMissesCache } from "@apollo/utils.keyvaluecache";

const redisCache = new Keyv(new KeyvRedis("redis://user:pass@localhost:6379"));
const faultTolerantCache = new ErrorsAreMissesCache(
  new KeyvAdapter(redisCache),
);
```

## Legacy caching implementation

Versions of Apollo Server prior to 3.9 use the `apollo-server-caching` package to implement caching. The `apollo-server-caching` package is no longer maintained, and we do not recommend using it. The `KeyValueCache` interface has been moved and is now in the `@apollo/utils.keyvaluecache` package.

The `InMemoryLRUCache` class has also moved to the `@apollo/utils.keyvaluecache` package. The `InMemoryLRUCache` class now uses version 7 of `lru-cache`, accepting different configuration options and no longer allowing a cache to be unbounded.

The `apollo-server-cache-redis` and `apollo-server-cache-memcached` packages are no longer receiving updates; we recommend using `keyv` instead, as shown above.
